package utils;

import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;


/**
 * Different global helping methods that are used throughout the project.
 */
public class Utils {

    public static String valueOf (int [] values) {
        StringBuffer sb = new StringBuffer ();
        for (int i = 0; i < values.length; i++) {
            sb.append (values[i]);
            if (i < values.length - 1)
                sb.append (" ");
        }

        return sb.toString();
    }
    
    public static String valueOf (String [] values) {
        StringBuffer sb = new StringBuffer ();
        for (int i = 0; i < values.length; i++) {
            sb.append (values[i]);
            if (i < values.length - 1)
                sb.append (" ");
        }

        return sb.toString();
    }
    
	public static String boolToNum(boolean b)  {
		return (b == true) ? "1" : "0";
	}
	
    public static String [] convertToStringArray (String text) {
        StringTokenizer st = new StringTokenizer (text, " ");
        String [] values = new String [st.countTokens()];

        // Populate line info array
        for (int i = 0; i < values.length; i++) {
            values [i] = st.nextToken().trim();
        }

        return values;
    }
    
    public static boolean charToBool(char c) {
    	return String.valueOf(c).equals("1"); // ? true : false;
    }
    
    public static int charToInt (char c) {
    	return Integer.valueOf(String.valueOf(c));
    }
    
    /**
     * Return the given string, beginning with a capital letter and all the rest are lower case letters. <br>
     * For example - For all the following input : "TEST", "test", "tEST", "TeSt" etc., the text returned will be "Test"
     *   
     * @param string - The string to perform on.
     * @return The new string, beginning with a capital letter and all the rest are lower case letters.
     */
    public static String beginWithCapital(String string)
    {
		return string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase(); // Output: Normal
    }
    
	public static BufferedImage getScaledImage(BufferedImage bufferedImageToSacle, double width , double height) {
		AffineTransform at = AffineTransform.getScaleInstance( width /bufferedImageToSacle.getWidth(), height/bufferedImageToSacle.getHeight());
		AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
		BufferedImage bufferedImageScaled = op.filter(bufferedImageToSacle, null);
		return bufferedImageScaled;
	}
	
	public static BufferedImage getScaledImage(BufferedImage bufferedImageToSacle, double width) {

		AffineTransform at = AffineTransform.getScaleInstance((double) (width /bufferedImageToSacle.getWidth()), (width * (((double)bufferedImageToSacle.getHeight()) / ((double)bufferedImageToSacle.getWidth())))  / bufferedImageToSacle.getHeight());
		AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
		BufferedImage buffredImageScaled = op.filter(bufferedImageToSacle, null);
		return buffredImageScaled;
	}
	
	public static Image toImage(BufferedImage bufferedImage) { 
		return Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource());
	}
	
	public static Rectangle2D getStringBounds(String text, Graphics g)
	{
		FontMetrics fm = g.getFontMetrics();
		
		return fm.getStringBounds(text, g);
	}
	
    public static BufferedImage toBufferedImage(Image image) { 
    	if (image instanceof BufferedImage) {
    		return (BufferedImage)image;
    	}
    	
	    image = new ImageIcon(image).getImage();
	    
	    boolean hasAlpha = hasAlpha(image);
	    
	    BufferedImage bimage = null; 
	    
	    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
	    try {
			int transparency = Transparency.OPAQUE; 
			if (hasAlpha) {
				transparency = Transparency.BITMASK;
			}
			// Create the buffered image 
			GraphicsDevice gs = ge.getDefaultScreenDevice(); 
			GraphicsConfiguration gc = gs.getDefaultConfiguration();
			bimage = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency);
		} 
	    catch (HeadlessException e) { 
	    	 e.printStackTrace();
	    }
	    
		if (bimage == null) {
			// Create a buffered image using the default color model
			int type = BufferedImage.TYPE_INT_RGB; 
			if (hasAlpha) { 
				type = BufferedImage.TYPE_INT_ARGB;
			} 
			bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
		} 
		
		// Copy image to buffered image
		Graphics g = bimage.createGraphics();
		
		// Paint the image onto the buffered 
		g.drawImage(image, 0, 0, null);
		g.dispose(); 
		return bimage;
	}

	public static boolean hasAlpha(Image image) {
		if (image instanceof BufferedImage) {
			BufferedImage bimage = (BufferedImage)image;
			return bimage.getColorModel().hasAlpha();
		} 
		PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
		try {
			pg.grabPixels(); 
		} 
		catch (InterruptedException e) {
			
		}
		// Get the image's color model 
		ColorModel cm = pg.getColorModel();
		return cm.hasAlpha(); 
	}
	
	public static boolean isUserPlayingInATable(TableList tableList, String username)
	{
		boolean isUserPlaying = false;
		
		for (int currTableNumber : tableList.getTablesNumbers())
		{
			Table currTable = tableList.getTable(currTableNumber);
			
			if (currTable.getPlayingPlayersNames().contains(username))
			{
				isUserPlaying = true;
				break;
			}
		}
		
		return isUserPlaying;
	}
}
